﻿/********************************************************************************/
// <copyright file="UnitOfWork.cs" company="Asia E-Business Solutions">
//     Copyright © 2012. All right reserved
// </copyright>
//
// <history>
//  <change who="Hieu Nguyen" date="11/12/2012 12:08:27 PM">Created</change>
// <history>
/********************************************************************************/

namespace JLL.China.Infrastructure.UnitOfWork
{
    using System.Collections.Generic;
    using System.Transactions;
    using JLL.China.Infrastructure.DomainBase;
    using JLL.China.Infrastructure.RepositoryFramework;

    public class UnitOfWork<T> : IUnitOfWork<T> where T : new()
    {
        private Dictionary<IEntity<T>, IUnitOfWorkRepository<T>> addedEntities;
        private Dictionary<IEntity<T>, IUnitOfWorkRepository<T>> changedEntities;
        private Dictionary<IEntity<T>, IUnitOfWorkRepository<T>> deletedEntities;

        public UnitOfWork()
        {
            this.addedEntities = new Dictionary<IEntity<T>, IUnitOfWorkRepository<T>>();
            this.changedEntities = new Dictionary<IEntity<T>, IUnitOfWorkRepository<T>>();
            this.deletedEntities = new Dictionary<IEntity<T>, IUnitOfWorkRepository<T>>();
        }


        public void RegisterAdded(IEntity<T> entity, IUnitOfWorkRepository<T> repository)
        {
            this.addedEntities.Add(entity, repository);
        }

        public void RegisterChanged(IEntity<T> entity,
            IUnitOfWorkRepository<T> repository)
        {
            this.changedEntities.Add(entity, repository);
        }

        public void RegisterRemoved(IEntity<T> entity,
            IUnitOfWorkRepository<T> repository)
        {
            this.deletedEntities.Add(entity, repository);
        }

        public virtual void Commit()
        {
            using (TransactionScope scope = new TransactionScope())
            {
                foreach (IEntity<T> entity in this.deletedEntities.Keys)
                {
                    this.deletedEntities[entity].PersistDeletedItem(entity);
                }

                foreach (IEntity<T> entity in this.addedEntities.Keys)
                {
                    this.addedEntities[entity].PersistNewItem(entity);
                }

                foreach (IEntity<T> entity in this.changedEntities.Keys)
                {
                    this.changedEntities[entity].PersistUpdatedItem(entity);
                }

                scope.Complete();
            }

            this.deletedEntities.Clear();
            this.addedEntities.Clear();
            this.changedEntities.Clear();
        }
    }
}
